#include "VelocityFieldVisualizer.h"
#include "ParticleSys.h"
#include "GridField.h"
#include "RenderMiscs.h"
#include <iostream>
#include "DecoLogger.h"

#define VORTICITY_THRESHOLD 1
#define PARTICLE_PICK_INTEVAL 1

VelocityFieldVisualizer::VelocityFieldVisualizer() : mGrid(NULL), mParticleSys(NULL)
{

}


VelocityFieldVisualizer::VelocityFieldVisualizer(GridField* grid, ParticleSys* particleSys)
{
	SetGrid(grid);
	SetParticleSys(particleSys);
}

VelocityFieldVisualizer::~VelocityFieldVisualizer()
{
	
}

void VelocityFieldVisualizer::Render(DecoRenderInterface* RI, DecoLight** Lights, UINT numEffectiveLights) const
{
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glRotatef(90.0f, 1, 0, 0);
	matrix44 mat;
	glGetDoublev(GL_MODELVIEW_MATRIX, (double*)&mat);
	glLoadIdentity();

	matrix44 mat2;
	RI->GetTransform(TT_LocalToWorld, mat2);
	RI->SetTransform(TT_LocalToWorld, mat * mat2);

	const std::list<Particle>& particles = mParticleSys->GetAllParticles();
	if (particles.size())
	{	
		vector<vector3> particlePos;
		vector<DecoColor> particleCol;
		UINT i = 0;
		int count = 0;

		DecoColor col(255, 255, 255);

		for (list<Particle>::const_iterator it = particles.begin(); it != particles.end();++it)
		{
			count++;

			if (count % PARTICLE_PICK_INTEVAL)
				continue;


			std::vector<vector3> points;
			std::vector<DecoColor> colors;
			(*it).m_trace.GetWholeTrace(points);
			colors.resize(points.size());
			double maxVortexMag = 0;
			for (size_t i = 0; i < colors.size(); ++i)
			{
				double vorticityValue = (*it).m_vorticity;//mGrid->SampleScalerValue(points[i], mGrid->mVorticity);
				maxVortexMag += vorticityValue * vorticityValue;
				double vortMag = 50 * vorticityValue;
				if (vortMag > 255)
					vortMag = 255;
				if (vortMag < -255)
					vortMag = -255;

				double ratio = (vortMag + 255) / (255 * 2);
				double magnitude = pow(abs(vortMag) / 255.0, 0.1);
				
				//col = DecoColor(static_cast<BYTE>(ratio * 255 * magnitude), 0, static_cast<BYTE>((1 - ratio) * 255 * magnitude));
				colors[i] = col;
			}
			if (maxVortexMag <= VORTICITY_THRESHOLD)
				continue;
			if (points.size())
				DecoRenderMisc::GetSingleton()->DrawLineStrip(&points[0], &colors[0], static_cast<UINT>(points.size()), 1);


		}
			
	}

	RI->SetTransform(TT_LocalToWorld, mat2);
}
void VelocityFieldVisualizer::SetGrid(GridField* grid)
{
	mGrid = grid;
}
void VelocityFieldVisualizer::SetParticleSys(ParticleSys* particleSys)
{
	mParticleSys = particleSys;
}

void VelocityFieldVisualizer::SaveToFile(const string& fileName)
{
	std::ofstream outFile(fileName.c_str());

	const std::list<Particle>& particles = mParticleSys->GetAllParticles();
	int count = 0;
	if (particles.size())
	{	
		for (list<Particle>::const_iterator it = particles.begin(); it != particles.end();++it)
		{
			count++;

			if (count % PARTICLE_PICK_INTEVAL)
				continue;


			std::vector<vector3> points;

			(*it).m_trace.GetWholeTrace(points);
			outFile << (*it).m_life << std::endl;

			for (size_t i = 0; i < points.size(); ++i)
			{
				double vorticityValue = (*it).m_vorticity;//mGrid->SampleScalerValue(points[i], mGrid->mVorticity);
				outFile << vorticityValue << " ";
			}
			outFile << std::endl;

			for (size_t i = 0; i < points.size(); ++i)
			{
				outFile << points[i].x << " " << points[i].y << " " << points[i].z << " ";
			}
			outFile << std::endl;

		}

	}
}